/**
 * Class will represent the universe
 * @author LoveIsLikeSand
 * @version 1.0
 *
 */ 

import java.awt.Point;
import java.io.Serializable;

/**
 * Universe
 * @author kushagramansingh
 * @version 1.0
 */
public class Universe implements Serializable{
	
	/**
	 * Names of the systems
	 */
	private String[] names = {"Omicron Percei 8", "Traal",
			"Somolia", "LaBeanville", "Omega", "Utopia", "SanatAUniverse", 
			"Epsilon 4", "College Park", "Midtown", "New Somolia", 
			"Tokyo 2.0", "Lawrencia", "Gotham", 
			"People's United Space Federation", "Skrillex", "Neo-Rome",
			"Dreamland", "Best Place Ever", "Disney", "Oberon"};
	
	/**
	 * - 0 ANARCHY
	 * - 1 COMMUNISM
	 * - 2 DEMOCRACY (CAPATALISM)
	 * - 3 MONARCHY
	 * - 4 THEOCRACY 
	 */
	private int[] govts = {0, 2, 0, 4, 3, 1, 2, 2, 3, 1, 2, 3, 2, 4, 1, 0, 4, 3, 0, 2, 3};
	
	/**
	 * - 0 NOSPECIALRESOURCES (the most common)
	 * - 1 Land is made of sugar
	 * - 2 Land is diabetic
	 * - 3 Warlike
	 * - 4 Hippies
	 * - 5 Land is made of heroin
	 * - 6 Too many junkies
	 * - 7 Too many doctors
	 * - 8 Too many malpractice suits
	 * - 9 Planet is Pluto
	 * - 10 Planet is made of plastic
	 * - 11 Indie game studios
	 * - 12 EA studios owns planet
	 * - 13 Too much water
	 * - 14 Desert
	 */
	/**
	 * - 0 Pre-Agriculture

		- 1 Agriculture

		- 2 Medieval

		- 3 Renaissance

		- 4 Early Industrial

		- 5 Industrial

		- 6 Post-Industrial

		- 7 Hi-Tech

	 */
	
	/**
	 * The total number of solar systems
	 */
	private int noOfSystems = 20;
	
	/**
	 * The array backing the universe
	 */
	private SolarSystem[] uni = new SolarSystem[noOfSystems];

	/**
	 * Constructor for Universe
	 */
	public Universe(){
		uni[0] = new SolarSystem(names[0], govts[0], (int) (Math.random() * 14),
				7, new Point(265, 142));
		for(int i=1;i < noOfSystems;i++){
			uni[i]= new SolarSystem(names[i], govts[i], (int) (Math.random() * 14),
					(int) (Math.random() * 7), assignPoints(govts[i]));
		}
	}
	
	/**
	 * Returns an array of the SolarSystems in this Universe
	 * @return uni
	 */
	public SolarSystem[] getSystems(){
		return uni;
	}
	
	/**
	 * An internal method that assigns points based on governments
	 * @param gov level
	 * @return the point
	 */
	public final Point assignPoints(int gov){
		Point point = null;
		int radius = (6 - gov) * 40;
		//500, 325
		while(!isValid(point)){
			point = generateNewPoint(radius);
		}
		return point;
	}
	
	/**
	 * Generates a new point within given radius from the center
	 * @param radius given
	 * @return the point
	 */
	public Point generateNewPoint(int radius){
		double randNum = Math.random() * (2 * Math.PI);
		int x = (int) (radius * Math.sin(randNum) + uni[0].getPoint().x);
		int y = (int) (radius * Math.cos(randNum) + uni[0].getPoint().y);
		
		return new Point(x, y);
	}
	
	/**
	 * Checks if the point does not conflict with another system
	 * @param p point
	 * @return whether valid
	 */
	public boolean isValid(Point p){
		if(p != null && (p.x >= 0 && p.x <= 590 && p.y >= 0 && p.y <= 300)){
			for(int i = 0;uni[i] != null && i < uni.length - 1; i++){
				if((Math.abs(uni[i].getPoint().x - p.x) < 60 &&
						Math.abs(uni[i].getPoint().y - p.y) < 60)){
					return false;
				}
			}
			return true;
		}
		else{
			return false;
		}
	}
}
